package com.ruoyi.project.manage.project.service.impl;

import com.ruoyi.common.constant.ProjectConstants;
import com.ruoyi.project.manage.project.domain.Project;
import com.ruoyi.project.manage.project.mapper.ProjectMapper;
import com.ruoyi.project.manage.project.mapper.ProjectStatMapper;
import com.ruoyi.project.manage.project.service.IProjectStatService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

/**
 * 项目统计Service业务层处理
 * 
 * @author fangkun
 * @date 2022-03-28
 */
@Service
public class ProjectStatServiceImpl implements IProjectStatService
{
    @Autowired
    private ProjectMapper projectMapper;
    @Autowired
    private ProjectStatMapper projectStatMapper;

    private static String KEY_TOTAL = "totalNum";
    private static String KEY_PERCENT = "percent";

    @Override
    public int getAllCount() {
        Project project = new Project();
        project.setProjectStatus(ProjectConstants.APPROVAL_AGREE);
        Map totalStat = projectStatMapper.getTotalStat(project);
        return (Integer) totalStat.get("totalNum");
    }

    @Override
    public List<Map> getAreaCount() {
        Project project = new Project();
        project.setProjectStatus(ProjectConstants.APPROVAL_AGREE);
        return calPercentByTotal(KEY_TOTAL, KEY_PERCENT, projectStatMapper.getColumnStat("project_area", "eb_project_area", project));
    }

    /**
     * 投资建设资金情况统计
     *
     * @return
     */
    @Override
    public Map getAllInvest() {
        Project project = new Project();
        project.setProjectStatus(ProjectConstants.APPROVAL_AGREE);
        return projectStatMapper.getTotalStat(project);
    }

    @Override
    public List<Map> getAreaInvest() {
        Project project = new Project();
        project.setProjectStatus(ProjectConstants.APPROVAL_AGREE);
        // 计算数量百分比
        List<Map> percentList = calPercentByMax(KEY_TOTAL, KEY_PERCENT, projectStatMapper.getAreaTotalStat(project));
        // 计算总投资百分比
        Double totalNumMax = percentList.stream().mapToDouble(data -> ((BigDecimal) data.get("totalInvestSum")).doubleValue()).max().getAsDouble();
        percentList = doCalPercent("totalInvestSum", "totalPercent", percentList, new BigDecimal(totalNumMax));
        // 计算计划投资百分比
        Double planSumMax = percentList.stream().mapToDouble(data -> ((BigDecimal) data.get("planInvestSum")).doubleValue()).max().getAsDouble();
        percentList = doCalPercent("planInvestSum", "planPercent", percentList, new BigDecimal(planSumMax));
        // 计算实际投资百分比
        Double doneSumMax = percentList.stream().mapToDouble(data -> ((BigDecimal) data.get("doneInvestSum")).doubleValue()).max().getAsDouble();
        percentList = doCalPercent("doneInvestSum", "donePercent", percentList, new BigDecimal(doneSumMax));
        return percentList;
    }

    /**
     * 项目类型统计/投资额分布情况
     *
     * @return
     */
    @Override
    public List<Map> getAllType(boolean needArea, Project project) {
        if (project == null)  project = new Project();
        project.setProjectStatus(ProjectConstants.APPROVAL_AGREE);
        if (needArea) {
            return calPercentByMax(KEY_TOTAL, KEY_PERCENT, projectStatMapper.getAreaColumnStat("project_type", "eb_project_type", project));
        } else {
            return calPercentByTotal(KEY_TOTAL, KEY_PERCENT, projectStatMapper.getColumnStat("project_type", "eb_project_type", project));
        }
    }

    /**
     * 建设性质统计
     *
     * @return
     */
    @Override
    public List<Map> getAllConstructionType(boolean needArea) {
        Project project = new Project();
        project.setProjectStatus(ProjectConstants.APPROVAL_AGREE);
        if (needArea) {
            return calPercentByMax(KEY_TOTAL, KEY_PERCENT, projectStatMapper.getAreaColumnStat("construction_type", "eb_construction_type", project));
        } else {
            return calPercentByTotal(KEY_TOTAL, KEY_PERCENT, projectStatMapper.getColumnStat("construction_type", "eb_construction_type", project));
        }
    }

    /**
     * 项目阶段情况统计
     *
     * @return
     */
    @Override
    public List<Map> getAllStage(boolean needArea) {
        Project project = new Project();
        project.setProjectStatus(ProjectConstants.APPROVAL_AGREE);
        if (needArea) {
            return calPercentByMax(KEY_TOTAL, KEY_PERCENT, projectStatMapper.getAreaColumnStat("project_stage", "eb_project_stage", project));
        } else {
            return calPercentByTotal(KEY_TOTAL, KEY_PERCENT, projectStatMapper.getColumnStat("project_stage", "eb_project_stage", project));
        }
    }

    /**
     * 七大产业集群统计
     *
     * @return
     */
    @Override
    public List<Map> getAllIndustryByType(boolean needArea) {
        Project project = new Project();
        project.setProjectStatus(ProjectConstants.APPROVAL_AGREE);
        project.setProjectType(20);
        if (needArea) {
            return calPercentByMax(KEY_TOTAL, KEY_PERCENT, projectStatMapper.getAreaColumnStat("project_industry", "eb_project_industry", project));
        } else {
            return calPercentByMax(KEY_TOTAL, KEY_PERCENT, projectStatMapper.getColumnStat("project_industry", "eb_project_industry", project));
        }
    }

    /**
     * “三个一批”项目统计
     *
     * @return
     */
    @Override
    public List<Map> getAllProgress(boolean needArea) {
        Project project = new Project();
        project.setProjectStatus(ProjectConstants.APPROVAL_AGREE);
        project.setProjectLabel(ProjectConstants.LABEL_THREE_ONE + "");
        if (needArea) {
            return calPercentByMax(KEY_TOTAL, KEY_PERCENT, projectStatMapper.getAreaColumnStat("project_progress", "eb_project_progress", project));
        } else {
            return calPercentByTotal(KEY_TOTAL, KEY_PERCENT, projectStatMapper.getColumnStat("project_progress", "eb_project_progress", project));
        }
    }

    /**
     * 各区项目数量统计
     *
     * @return
     */
    @Override
    public int getAreasCount(Integer projectArea) {
        Project project = new Project();
        project.setProjectStatus(ProjectConstants.APPROVAL_AGREE);
        project.setProjectArea(projectArea);
        Map totalStat = projectStatMapper.getTotalStat(project);
        return (Integer) totalStat.get("totalNum");
    }

    /**
     * 各区投资建设资金情况统计
     *
     * @return
     */
    @Override
    public Map getAreasInvest(Integer projectArea) {
        Project project = new Project();
        project.setProjectStatus(ProjectConstants.APPROVAL_AGREE);
        project.setProjectArea(projectArea);
        return projectStatMapper.getTotalStat(project);
    }

    /**
     * 各区项目类型统计/投资额分布情况
     *
     * @return
     */
    @Override
    public List<Map> getAreasType(Integer projectArea) {
        Project project = new Project();
        project.setProjectStatus(ProjectConstants.APPROVAL_AGREE);
        project.setProjectArea(projectArea);
        return calPercentByTotal(KEY_TOTAL, KEY_PERCENT, projectStatMapper.getColumnStat("project_type", "eb_project_type", project));
    }

    /**
     * 各区建设性质统计
     *
     * @return
     */
    @Override
    public List<Map> getAreasConstructionType(Integer projectArea) {
        Project project = new Project();
        project.setProjectStatus(ProjectConstants.APPROVAL_AGREE);
        project.setProjectArea(projectArea);
        return calPercentByTotal(KEY_TOTAL, KEY_PERCENT, projectStatMapper.getColumnStat("construction_type", "eb_construction_type", project));
    }

    /**
     * 各区项目阶段情况统计
     *
     * @return
     */
    @Override
    public List<Map> getAreasStage(Integer projectArea) {
        Project project = new Project();
        project.setProjectStatus(ProjectConstants.APPROVAL_AGREE);
        project.setProjectArea(projectArea);
//        project.setProjectStage(ProjectConstants.PROJECT_PREPARE);
        return calPercentByTotal(KEY_TOTAL, KEY_PERCENT, projectStatMapper.getColumnStat("project_stage", "eb_project_stage", project));
    }

    /**
     * 各区七大产业集群统计
     *
     * @return
     */
    @Override
    public List<Map> getAreasIndustryByType(Integer projectArea) {
        Project project = new Project();
        project.setProjectStatus(ProjectConstants.APPROVAL_AGREE);
        project.setProjectType(20);
        project.setProjectArea(projectArea);
        return calPercentByMax(KEY_TOTAL, KEY_PERCENT, projectStatMapper.getColumnStat("project_industry", "eb_project_industry", project));
    }

    @Override
    public List<Map> getAreasProgress(Integer projectArea) {
        Project project = new Project();
        project.setProjectStatus(ProjectConstants.APPROVAL_AGREE);
        project.setProjectArea(projectArea);
        project.setProjectLabel(ProjectConstants.LABEL_THREE_ONE + "");
        return calPercentByTotal(KEY_TOTAL, KEY_PERCENT, projectStatMapper.getColumnStat("project_progress", "eb_project_progress", project));
    }

    private List<Map> calPercentByTotal(String key, String putKey, List<Map> datas) {
        // 获取统计总数的合集
        Long totalNumSum = datas.stream().mapToLong(data -> (Long) data.get(key)).sum();
        return doCalPercent(key, putKey, datas, totalNumSum);
    }

    private List<Map> calPercentByMax(String key, String putKey, List<Map> datas) {
        // 获取统计总数的最大值
        Long totalNumMax = datas.stream().mapToLong(data -> (Long) data.get(key)).max().getAsLong();
        return doCalPercent(key, putKey, datas, totalNumMax);
    }

    private List<Map> doCalPercent(String key, String putKey, List<Map> datas, long denominator) {
        datas.stream().forEach(data -> {
            // 取每一个统计总数
            BigDecimal totalNum = new BigDecimal((Long) data.get(key));
            // 当总数或者当前统计总数为0，则直接赋值0
            if (denominator == 0l || totalNum.longValue() == 0) {
                data.put(putKey, 0l);
            } else {
                // 统计总数/最大值，设置2位小数，四舍五入
                totalNum = totalNum.divide(new BigDecimal(denominator),2,BigDecimal.ROUND_HALF_UP);
                // 乘以100
                totalNum = totalNum.multiply(new BigDecimal(100));
                // 输出占比
                data.put(putKey, totalNum.intValue());
            }

        });
        return datas;
    }

    private List<Map> doCalPercent(String key, String putKey, List<Map> datas, BigDecimal denominator) {
        datas.stream().forEach(data -> {
            // 取每一个统计总数
            BigDecimal totalNum = (BigDecimal) data.get(key);
            // 当总数或者当前统计总数为0，则直接赋值0
            if (denominator == BigDecimal.ZERO || totalNum.longValue() == 0) {
                data.put(putKey, 0l);
            } else {
                // 统计总数/最大值，设置2位小数，四舍五入
                totalNum = totalNum.divide(denominator,2,BigDecimal.ROUND_HALF_UP);
                // 乘以100
                totalNum = totalNum.multiply(new BigDecimal(100));
                // 输出占比
                data.put(putKey, totalNum.intValue());
            }

        });
        return datas;
    }

    @Override
    public List<Map> getAreasProject(Project project) {
//        project.setProjectStage(ProjectConstants.PROJECT_PREPARE);
        return projectStatMapper.getProjectList(project);
    }
}
